package com.hmkj.core.service.commo.impl;

import com.hmkj.common.baseMapper.GenericMapper;
import com.hmkj.common.baseMapper.GenericPo;
import com.hmkj.core.constant.CacheID;
import com.hmkj.core.constant.RiskNID;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.mapper.commo.CommoMapper;
import com.hmkj.core.model.order.CommoModel;
import com.hmkj.core.po.commo.Commo;
import com.hmkj.core.po.risk.RiskParam;
import com.hmkj.core.service.cache.RedisService;
import com.hmkj.core.service.commo.CommoService;
import com.hmkj.core.service.risk.RiskParamService;
import com.xiaoleilu.hutool.util.BeanUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 交易品种表业务相关Service接口实现<br>
 *
 * @author eproo
 * @ClassName: CommoServiceImpl
 * @date 2017-11-07 02:22:12
 */
@Service
@Scope("prototype")
@Transactional(rollbackFor = Exception.class)
public class CommoServiceImpl implements CommoService {

    @Resource
    private CommoMapper commoMapper;
    @Resource
    private RiskParamService riskParamService;
    @Resource
    private RedisService redisService;

    @Override
    public GenericMapper<Commo, Integer> _getMapper() {
        return commoMapper;
    }

    @Override
    public void doAdd(Commo model) throws Exception {
        //重复性校验
        List<Commo> commoList1 = commoMapper.select(new Commo(u -> {
            u.setName(model.getName());
            u.setType(model.getType());
            u.setDelFlag(Commo.DELFLAG.NORMAL.code);
        }));
        List<Commo> commoList2 = commoMapper.select(new Commo(u -> {
            u.setCode(model.getCode());
            u.setType(model.getType());
            u.setDelFlag(Commo.DELFLAG.NORMAL.code);
        }));
        if (CollectionUtils.isNotEmpty(commoList1) || CollectionUtils.isNotEmpty(commoList2)) {
            throw new BussinessException("该品种名称或者品种代码已存在，请不要重复添加");
        }
        model.setStatus(Commo.STATUS.T2.code);
        commoMapper.insert(model);
        Commo commo = commoMapper.selectOne(new Commo(c ->{ c.setCode(model.getCode());}));
        //初始化品种风控参数copy已启用的风控参数
        List<Commo> commoList = commoMapper.select(new Commo(t ->{
            t.setDelFlag(Commo.DELFLAG.NORMAL.code);
            t.setStatus(Commo.STATUS.T1.code);
        }));
        if(null != commoList && commoList.size()>0){//有未被禁用的品种则直接复制--以供管理员参考修改
            Commo co = commoList.get(0);
            List<RiskParam> riskParamList = riskParamService.select(new RiskParam(r ->{
                r.setCommoId(co.getId());
            }));
            for (RiskParam r : riskParamList) {
                RiskParam riskParam = new RiskParam();
                riskParam.setCommoId(commo.getId());
                riskParam.setName(r.getName());
                riskParam.setNid(r.getNid());
                riskParam.setValue(r.getValue());
                riskParam.setDescript(r.getDescript());
                riskParamService.insert(riskParam);
            }
        }else{//如果全被禁用则提示需要启用一个品种
            throw new BussinessException("添加品种失败，原因：初始化品种风控参数失败，至少需要一个品种是启用状态");
        }

        redisService.put(CacheID.COMMO_LIST, commoList);
        commoList.forEach(com -> {
            redisService.put(CacheID.COMMO_ID_PREFIX + com.getId(), com);
            redisService.put(CacheID.COMMO_CODE_PREFIX + com.getCode(), com);
        });

        //将风控参数重新放入缓存
        List<RiskParam> list = riskParamService.select(new RiskParam());
        for (RiskParam param : list) {
            redisService.put(CacheID.RISK_PREFIX + param.getNid() + ":" + param.getCommoId(), param.getValue());
        }
    }

    @Override
    public void doEdit(Commo model) throws Exception {
        Commo commo = commoMapper.selectOne(new Commo(u -> {
            u.setId(model.getId());
            u.setDelFlag(Commo.DELFLAG.NORMAL.code);
        }));
        if (null == commo) {
            throw new BussinessException("该品种不存在");
        }
        Commo checkModel = new Commo();
        checkModel.setId(model.getId());
        checkModel.setName(model.getName());
        checkModel.setCode(model.getCode());
        checkModel.setType(model.getType());
        checkModel.setDelFlag(Commo.DELFLAG.NORMAL.code);
        int result = commoMapper.checkRepeatSql(checkModel);
        if (result > 0) {
            throw new BussinessException("该品种已存在，请不要重复设置");
        }
        commoMapper.updateByPrimaryKeySelective(new Commo(u -> {
            u.setId(model.getId());
            u.setName(model.getName());
            u.setCode(model.getCode());
            u.setType(model.getType());
            u.setIcon(model.getIcon());
            u.setSortNo(model.getSortNo());
            u.setDecription(model.getDecription());
            u.setDelFlag(Commo.DELFLAG.NORMAL.code);
        }));

        List<Commo> commoList = commoMapper.select(new Commo(t ->{
            t.setDelFlag(Commo.DELFLAG.NORMAL.code);
            t.setStatus(Commo.STATUS.T1.code);
        }));
        redisService.put(CacheID.COMMO_LIST, commoList);
        commoList.forEach(com -> {
            redisService.put(CacheID.COMMO_ID_PREFIX + com.getId(), com);
            redisService.put(CacheID.COMMO_CODE_PREFIX + com.getCode(), com);
        });
    }

    @Override
    public List<CommoModel> selectModelList() {
        List<Commo> list = redisService.getList(CacheID.COMMO_LIST, Commo.class);
        if (CollectionUtils.isEmpty(list)) {
            list = commoMapper.select(new Commo(t -> {
                t.setStatus(Commo.STATUS.T1.code);
                t.setDelFlag(GenericPo.DELFLAG.NORMAL.code);
            }));
        }

        List<CommoModel> mlist = new ArrayList<>();
        for (Commo commo : list) {
            CommoModel model = new CommoModel();
            BeanUtil.copyProperties(commo, model);
            model.setCode(commo.getCode());
            model.setContract(riskParamService.getContractNo(commo.getId()));
            model.setExchType(riskParamService.getParamValue(RiskNID.EXCH_TYPE, commo.getId()));
            mlist.add(model);
        }
        return mlist;
    }
}
